﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace UI
{
    [RequireComponent(typeof(Mask))]
    public class AutoScrollContent : MonoBehaviour
    {
        // 局限性：内容 RectTransform 的轴必须在 RectTransform 的边上（需要先手动调整）
        // 目前只支持内容向左滑动或向上滑动（与阅读习惯一致）
        // 如果内容的 RectTransform 会动态变化（例如文字内容），需要在 Text 组件同一 GameObject 上添加 ContentSizeFitter 组件

        public bool isVerticleScroll;
        public float scrollVelocity;
        public bool isLoop;
        public RectTransform contentRectTransform;
        public float startDelay;
        public float endDelay;
        // 对于文字内容，起始位置的字符可能会被 Mask 组件遮挡到一小部分。可以通过 startPositionPadding 来调整内容的起始位置，避免这个问题
        public float startPositionPadding = 0f;
        public bool ignoreTimeScale = true;

        private RectTransform parentRectTransform;
        private float parentRectHeight;
        private float parentRectWidth;
        private float contentRectHeight;
        private float contentRectWidth;
        private bool isContentAtStartPos;
        private bool isContentAtEndPos;
        private float startCounter;
        private float endCounter;

        // Use this for initialization
        void Start()
        {
            parentRectTransform = this.GetComponent<RectTransform>();

            if (parentRectTransform != null)
            {
                parentRectHeight = parentRectTransform.rect.height;
                parentRectWidth = parentRectTransform.rect.width;
            }

            if (contentRectTransform != null)
            {
                contentRectHeight = contentRectTransform.rect.height;
                contentRectWidth = contentRectTransform.rect.width;

                contentRectTransform.SetParent(parentRectTransform.transform);

                if (isVerticleScroll)
                {
                    contentRectTransform.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Top, 0f, contentRectWidth);
                }
                else
                {
                    contentRectTransform.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Left, 0f, contentRectHeight);
                }
                contentRectTransform.anchoredPosition = new Vector2(0f, 0f);
            }

            isContentAtStartPos = true;
            isContentAtEndPos = false;
            startCounter = 0f;
            endCounter = 0f;
        }

        // Update is called once per frame
        void Update()
        {
            float deltaTime = ignoreTimeScale ? Time.unscaledDeltaTime : Time.deltaTime;

            // 垂直滑动（目前只支持向上）
            if (isVerticleScroll)
            {
                // 每帧需要获取 contentRectHeight 和 contentRectWidth（因为其可能动态变化）
                contentRectHeight = contentRectTransform.rect.height;
                contentRectWidth = contentRectTransform.rect.width;

                if (contentRectHeight > parentRectHeight && !isContentAtEndPos)
                {
                    if (isContentAtStartPos && startDelay > 0f && startCounter <= startDelay)
                    {
                        startCounter += deltaTime;
                        return;
                    }

                    contentRectTransform.anchoredPosition += new Vector2(0f, deltaTime * scrollVelocity);
                    isContentAtStartPos = false;
                }


                if ((contentRectHeight - contentRectTransform.anchoredPosition.y) <= parentRectHeight && isLoop)
                {
                    isContentAtEndPos = true;

                    if (endDelay > 0f && endCounter <= endDelay)
                    {
                        endCounter += deltaTime;
                        return;
                    }

                    ResetToBeginning();
                    isContentAtStartPos = true;
                }
            }
            // 左右滑动（目前只支持向左）
            else
            {
                // 每帧需要获取 contentRectHeight 和 contentRectWidth（因为其可能动态变化）
                contentRectHeight = contentRectTransform.rect.height;
                contentRectWidth = contentRectTransform.rect.width;

                if (contentRectWidth > parentRectWidth && !isContentAtEndPos)
                {
                    if (isContentAtStartPos && startDelay > 0f && startCounter <= startDelay)
                    {
                        startCounter += deltaTime;
                        return;
                    }

                    contentRectTransform.anchoredPosition += new Vector2(-deltaTime * scrollVelocity, 0f);
                    isContentAtStartPos = false;
                }

                if ((contentRectWidth - Mathf.Abs(contentRectTransform.anchoredPosition.x)) <= parentRectWidth && isLoop)
                {
                    isContentAtEndPos = true;

                    if (endDelay > 0f && endCounter <= endDelay)
                    {
                        endCounter += deltaTime;
                        return;
                    }

                    ResetToBeginning();
                    isContentAtStartPos = true;
                }
            }
        }

        public void ResetToBeginning()
        {
            startCounter = 0f;
            endCounter = 0f;
            isContentAtStartPos = true;
            isContentAtEndPos = false;

            var sizeFitter = contentRectTransform.GetComponent<ContentSizeFitter>();
            // 只支持向上、向左滚动，其他的方向滚动，这里还得修改
            if (isVerticleScroll)
            {
                contentRectTransform.anchoredPosition = new Vector2(0f, -startPositionPadding);
                if(sizeFitter != null)
                    sizeFitter.SetLayoutVertical();
            }
            else
            {
                contentRectTransform.anchoredPosition = new Vector2(startPositionPadding, 0f);
                if (sizeFitter != null)
                    sizeFitter.SetLayoutHorizontal();
            }

            // 还原位置时，从左到右、从右到左、从上到下、从下到上有差别，但是暂时只支持向左滑动或向上滑动，所以还需要继续扩展
            //if (isLeft)
            //{

            //}
            //else
            //{

            //}
        }

        public void PlayFoward()
        {

        }
    }
}
